#ifndef __GE_RESOURCE_H__
#define __GE_RESOURCE_H__
#include "GE_Base.h"
namespace Syp
{
///A Resource is something that is usually managed(Garbage Collected) by the Engine by it's respective manager once it has been added to the engine. However this garbage collection is only performed when the user wants to(Can be called in another thread/during loading screens). Resources should be allocated on the heap only and not on the stack.
///This is because the ResourceManager is managing the Resources and cannot differentiate between objects created on the stack or heap, and will call delete on them. While this could have been forced by making the constructor private and forcing the user to use some static function like createResource(), i prefer using the new operator to allocate Resources and realised this problem late in development.
///
/// You may derive your classes from the Resource class if you wish for them to be managed by the ResourceManager. However you will need to do your own reference counting management by using addInstance()/removeInstance().
class SYPAPI Resource
{
	friend class UniqueRegistry<Resource>;
	friend class ResourceManager;
public:
	Resource(const String& filename);
	///Returns the number of instances this Resource currently has.
	inline PInt getNumInstances()
	{
		return ref;
	};

	inline const String& getFileName()
	{
		return fileName;
	}
	///Copy Constructor. Should derived classes of Resource need to define their own copy constructor, it is important to call the Resource Copy Constructor to prevent incorrect reference counts.
	Resource(const Resource& r);
	///Assignment operator overload. Should derived classes overload the = operator, it is a must to call Resource::operator =(const Resource& r);
	Resource& operator =(const Resource& r);
	///Dumps all information known about resource into logfile.
	virtual void dumpResourceInfo();
protected:
	void addInstance();
	void removeInstance();
	///Resources cannot be deleted by user, Manager handles them
	virtual ~Resource();
	///Boolean whether resource is totally loaded. Useful for async loading.
	bool loaded;

private:
	///file name such as "face.bmp"
	String fileName;
	///Number of references to this Resource
	PInt ref;
};
}
#endif //__GE_SOURCE_H__

//Depreceated
/////Changes the filename of this resource.
	/////Note: This should not be called by user in almost any circumstances as many resources are identified by their filename. By changing the filename, any undefined behaviour may occur. The reason for this functions existence is for File loading/External classes loading resources from disk. More importantly it is for functions/operations which dynamically create Resources like Font Meshes/Textures. fileName allows these dynamic resource creating functions to give the resource a unique name.
	//inline void setFileName(const String& name)
	//{
	//	fileName = name;
	//};
